#include "tos_k.h"

#define STK_SIZE_TASK_PRODUCER      512
#define STK_SIZE_TASK_CONSUMER      512

k_stack_t stack_task_producer[STK_SIZE_TASK_PRODUCER];
k_stack_t stack_task_consumer[STK_SIZE_TASK_CONSUMER];

k_task_t task_producer;
k_task_t task_consumer;

extern void entry_task_producer(void *arg);
extern void entry_task_consumer(void *arg);

k_mutex_t buffer_locker;
k_sem_t full;
k_sem_t empty;

#define RESOURCE_COUNT_MAX 3
uint32_t resource_buffer[RESOURCE_COUNT_MAX];
int resource_cursor;

void entry_task_producer(void *arg) {
    size_t item = 0;
    k_err_t err;
    while (K_TRUE) {
        err = tos_sem_pend(&empty, TOS_TIME_FOREVER);
        if (err != K_ERR_NONE) {
            continue;
        }
        err = tos_mutex_pend(&buffer_locker);
        if (err != K_ERR_NONE) {
            continue;
        }
        printf("produce : %d\n", item);
        resource_buffer[resource_cursor++] = item;
        tos_mutex_post(&buffer_locker);
        tos_sem_post(&full);
        tos_task_delay(1000);
        ++item;
    }
}

void entry_task_consumer(void *arg) {
    k_err_t err;
    while (K_TRUE) {
        err = tos_sem_pend(&full, TOS_TIME_FOREVER);
        if (err != K_ERR_NONE)continue;
        tos_mutex_pend(&buffer_locker);
        if (err != K_ERR_NONE)continue;
        printf("consume : %d\n", resource_buffer[--resource_cursor]);
        tos_mutex_post(&buffer_locker);
        tos_sem_post(&empty);
        tos_task_delay(1100);
    }
}

int main(void) {
    // 初始化资源缓冲区和指针
    memset(resource_buffer, 0, sizeof(uint32_t)*RESOURCE_COUNT_MAX);
    resource_cursor = 0;
    // 初始化TencentOS tiny内核
    tos_knl_init();
    // 创建互斥锁和信号量
    tos_mutex_create(&buffer_locker);
    tos_sem_create(&full, 0);
    tos_sem_create(&empty, RESOURCE_COUNT_MAX);
    // 创建生产者和消费者任务
    (void)tos_task_create(&task_producer, "producer", entry_task_producer, NULL,
                          4, stack_task_producer, STK_SIZE_TASK_PRODUCER, 0);
    (void)tos_task_create(&task_consumer, "consumer", entry_task_consumer, NULL,
                          4, stack_task_consumer, STK_SIZE_TASK_CONSUMER, 0);
    // 启动TencentOS tiny内核
    tos_knl_start();
}